package monolithicapp

import (
	"context"
	"log/slog"
	"os"
	"os/signal"
	"syscall"
	"time"
)

type Service interface {
	Start() error
	Stop(ctx context.Context) error
}

type Application struct {
	services []Service
	stop     chan os.Signal
}

func New() *Application {
	return &Application{
		stop: make(chan os.Signal, 1),
	}
}

func (a *Application) Register(svc Service) {
	a.services = append(a.services, svc)
}

func (a *Application) Run() error {
	// 启动所有服务
	for _, svc := range a.services {
		if err := svc.Start(); err != nil {
			return err
		}
	}

	// 等待终止信号
	signal.Notify(a.stop, syscall.SIGINT, syscall.SIGTERM)
	<-a.stop

	slog.Info("Application stopped...")
	// 优雅关闭
	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
	defer cancel()
	return a.Shutdown(ctx)
}

func (a *Application) Shutdown(ctx context.Context) error {
	// 逆序关闭服务
	for i := len(a.services) - 1; i >= 0; i-- {
		_ = a.services[i].Stop(ctx)
	}
	return nil
}
